package com.study.sync;

//第一步 创建资源类，定义属性和操作方法
class Share {
    //初始值
    private int number = 0;
    //+1的方法
    public synchronized void incr() throws InterruptedException {
        //第二步 判断 干活 通知
        //判断：number值是否是0，如果不是0，等待
        // if (number != 0) {  --> 会产生虚假唤醒问题，即只对第一次进入的条件进行了判断，使用while判断可以避免虚假唤醒
        while (number != 0) {
            //在哪里睡，就在哪里醒
            this.wait();
        }
        //干活：如果number值是0，就+1操作
        number++;
        System.out.println("当前线程名：" + Thread.currentThread().getName() + " :: " + number);
        //通知：通知其他线程
        this.notifyAll();
    }

    //-1的方法
    public synchronized void decr() throws InterruptedException {
        //判断：number值是否是1，如果不是1，等待
        // if (number != 1) {  --> 会产生虚假唤醒问题，即只对第一次进入的条件进行了判断，使用while判断可以避免虚假唤醒
        while (number != 1) {
            this.wait();
        }
        //干活：如果number值是1，就-1操作
        number--;
        System.out.println("当前线程名：" + Thread.currentThread().getName() + " :: " + number);
        //通知：通知其他线程
        this.notifyAll();
    }
}

public class ThreadDemo1 {
    //第三步 创建多个线程，调用资源类的操作方法
    public static void main(String[] args) {
        Share share = new Share();
        //创建线程
        // 创建线程 AA
        new Thread(() -> {
            for (int i = 1; i <= 10; i++) {
                try {
                    share.incr(); //+1
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "AA").start();
        // 创建线程 BB
        new Thread(() -> {
            for (int i = 1; i <= 10; i++) {
                try {
                    share.decr(); //-1
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "BB").start();
        // 创建线程 CC
        new Thread(() -> {
            for (int i = 1; i <= 10; i++) {
                try {
                    share.incr(); //+1
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "CC").start();
        // 创建线程 DD
        new Thread(() -> {
            for (int i = 1; i <= 10; i++) {
                try {
                    share.decr(); //-1
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "DD").start();
    }
}
